﻿// 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面
// (“Fluent UI”)。该示例仅供参考，
// 用以补充《Microsoft 基础类参考》和
// MFC C++ 库软件随附的相关电子文档。
// 复制、使用或分发 Fluent UI 的许可条款是单独提供的。
// 若要了解有关 Fluent UI 许可计划的详细信息，请访问
// https://go.microsoft.com/fwlink/?LinkId=238214.
//
// 版权所有(C) Microsoft Corporation
// 保留所有权利。

// CG2019112346张柳GDI2DView.cpp: CCG2019112346张柳GDI2DView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "CG2019112346张柳.h"
#endif

#include "CG2019112346张柳GDI2DDoc.h"
#include "CG2019112346张柳GDI2DView.h"
#include "MainFrm.h"
#include "UIEventListener.h"
#include "Create2DLineSegment.h"
#include "Create2DLine.h"
#include "Create2DRay.h"
#include "Create2DBrokenLine.h"
#include "Create2DCircle.h"
#include "Create2D3PointCircle.h"
#include "Create2DDiaCircle.h"
#include "Create2D3PointArc.h"
#include "Create2DSeedFill.h"
#include "Create2DPolygon.h"
#include "Translate2DRenderable.h"
#include "Scale2DRenderable.h"
#include "Move2DCamera.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include "CG2DClock.h"


// CCG2019112346张柳GDI2DView

IMPLEMENT_DYNCREATE(CCG2019112346张柳GDI2DView, CGDI2DView)

BEGIN_MESSAGE_MAP(CCG2019112346张柳GDI2DView, CGDI2DView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CGDI2DView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CGDI2DView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CCG2019112346张柳GDI2DView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_DRAW_CDC, &CCG2019112346张柳GDI2DView::OnDrawCdc)
	ON_WM_SIZE()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MBUTTONDOWN()
	ON_WM_MBUTTONDBLCLK()
	ON_WM_MBUTTONUP()
	ON_WM_MOUSEWHEEL()
	ON_WM_MOUSEMOVE()
	ON_WM_MOUSEHWHEEL()
	ON_WM_RBUTTONDBLCLK()
	ON_WM_RBUTTONDOWN()

	ON_UPDATE_COMMAND_UI(ID_LineSegment, &CCG2019112346张柳GDI2DView::OnUpdateLinesegment)
	ON_COMMAND(ID_LineSegment, &CCG2019112346张柳GDI2DView::OnLinesegment)
	ON_COMMAND(ID_CommandNone, &CCG2019112346张柳GDI2DView::OnCommandnone)
	ON_UPDATE_COMMAND_UI(ID_CommandNone, &CCG2019112346张柳GDI2DView::OnUpdateCommandnone)
	ON_COMMAND(ID_Pick_One, &CCG2019112346张柳GDI2DView::OnPickOne)
	ON_UPDATE_COMMAND_UI(ID_Pick_One, &CCG2019112346张柳GDI2DView::OnUpdatePickOne)
	ON_COMMAND(ID_Pick_All, &CCG2019112346张柳GDI2DView::OnPickAll)
	ON_COMMAND(ID_Pick_None, &CCG2019112346张柳GDI2DView::OnPickNone)
	ON_COMMAND(ID_Draw_2Dline, &CCG2019112346张柳GDI2DView::OnDraw2dline)
	ON_UPDATE_COMMAND_UI(ID_Draw_2Dline, &CCG2019112346张柳GDI2DView::OnUpdateDraw2dline)
	ON_COMMAND(ID_RAY, &CCG2019112346张柳GDI2DView::OnRay)
	ON_UPDATE_COMMAND_UI(ID_RAY, &CCG2019112346张柳GDI2DView::OnUpdateRay)
	ON_COMMAND(ID_Draw2dline_Time, &CCG2019112346张柳GDI2DView::OnDraw2dlineTime)
	ON_COMMAND(ID_Draw_Broken_Line, &CCG2019112346张柳GDI2DView::OnDrawBrokenLine)
	ON_UPDATE_COMMAND_UI(ID_Draw_Broken_Line, &CCG2019112346张柳GDI2DView::OnUpdateDrawBrokenLine)
	ON_UPDATE_COMMAND_UI(ID_Pick_All, &CCG2019112346张柳GDI2DView::OnUpdatePickAll)
	ON_COMMAND(ID_2Point_Radius, &CCG2019112346张柳GDI2DView::On2pointRadius)
	ON_UPDATE_COMMAND_UI(ID_2Point_Radius, &CCG2019112346张柳GDI2DView::OnUpdate2pointRadius)
	ON_COMMAND(ID_Diameter_Circle, &CCG2019112346张柳GDI2DView::OnDiameterCircle)
	ON_UPDATE_COMMAND_UI(ID_Diameter_Circle, &CCG2019112346张柳GDI2DView::OnUpdateDiameterCircle)
	ON_COMMAND(ID_THREEPOINT_CIRCLE, &CCG2019112346张柳GDI2DView::OnThreepointCircle)
	ON_UPDATE_COMMAND_UI(ID_THREEPOINT_CIRCLE, &CCG2019112346张柳GDI2DView::OnUpdateThreepointCircle)
	ON_COMMAND(ID_3Point_ARC, &CCG2019112346张柳GDI2DView::On3pointArc)
	ON_UPDATE_COMMAND_UI(ID_3Point_ARC, &CCG2019112346张柳GDI2DView::OnUpdate3pointArc)
	ON_COMMAND(ID_Area, &CCG2019112346张柳GDI2DView::OnArea)
	ON_UPDATE_COMMAND_UI(ID_Area, &CCG2019112346张柳GDI2DView::OnUpdateArea)
	ON_COMMAND(ID_Draw_Polygon, &CCG2019112346张柳GDI2DView::OnDrawPolygon)
	ON_UPDATE_COMMAND_UI(ID_Draw_Polygon, &CCG2019112346张柳GDI2DView::OnUpdateDrawPolygon)
	ON_COMMAND(ID_Transform_TranslateLeft, &CCG2019112346张柳GDI2DView::OnTransformTranslateleft)
	ON_COMMAND(ID_Transform_TranslateReft, &CCG2019112346张柳GDI2DView::OnTransformTranslatereft)
	ON_COMMAND(ID_Transform_TranslateUp, &CCG2019112346张柳GDI2DView::OnTransformTranslateup)
	ON_COMMAND(ID_Transform_TranslateDown, &CCG2019112346张柳GDI2DView::OnTransformTranslatedown)
	ON_COMMAND(ID_Amplification, &CCG2019112346张柳GDI2DView::OnAmplification)
	ON_COMMAND(ID_Narrow, &CCG2019112346张柳GDI2DView::OnNarrow)
	ON_COMMAND(ID_X_Axisymmetric, &CCG2019112346张柳GDI2DView::OnXAxisymmetric)
	ON_COMMAND(ID_Y_Axisymmetric, &CCG2019112346张柳GDI2DView::OnYAxisymmetric)
	ON_COMMAND(ID_Origin_Axisymmetric, &CCG2019112346张柳GDI2DView::OnOriginAxisymmetric)
	ON_COMMAND(ID_YX_Axisymmetric, &CCG2019112346张柳GDI2DView::OnYxAxisymmetric)
	ON_COMMAND(ID_Y_X_Axisymmetric, &CCG2019112346张柳GDI2DView::OnYXAxisymmetric)
	ON_COMMAND(ID_X_Shear, &CCG2019112346张柳GDI2DView::OnXShear)
	ON_COMMAND(ID_Y_Shear, &CCG2019112346张柳GDI2DView::OnYShear)
	ON_COMMAND(ID_Transform_Translate, &CCG2019112346张柳GDI2DView::OnTransformTranslate)
	ON_UPDATE_COMMAND_UI(ID_Transform_Translate, &CCG2019112346张柳GDI2DView::OnUpdateTransformTranslate)
	ON_COMMAND(ID_Big_Small, &CCG2019112346张柳GDI2DView::OnBigSmall)
	ON_UPDATE_COMMAND_UI(ID_Big_Small, &CCG2019112346张柳GDI2DView::OnUpdateBigSmall)
	ON_COMMAND(ID_Create_Clock, &CCG2019112346张柳GDI2DView::OnCreateClock)
	ON_WM_TIMER()
	ON_COMMAND(ID_Zoom_In, &CCG2019112346张柳GDI2DView::OnZoomIn)
	ON_COMMAND(ID_Camera_Pan, &CCG2019112346张柳GDI2DView::OnCameraPan)
	ON_UPDATE_COMMAND_UI(ID_Camera_Pan, &CCG2019112346张柳GDI2DView::OnUpdateCameraPan)
	ON_COMMAND(ID_Zoom_Out, &CCG2019112346张柳GDI2DView::OnZoomOut)
	ON_COMMAND(ID_Show_All, &CCG2019112346张柳GDI2DView::OnShowAll)
END_MESSAGE_MAP()

// CCG2019112346张柳GDI2DView 构造/析构

CCG2019112346张柳GDI2DView::CCG2019112346张柳GDI2DView() noexcept
{
	// TODO: 在此处添加构造代码

}

CCG2019112346张柳GDI2DView::~CCG2019112346张柳GDI2DView()
{
}

BOOL CCG2019112346张柳GDI2DView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CCG2019112346张柳GDI2DView 绘图

void CCG2019112346张柳GDI2DView::OnDraw(CDC* pDC)
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	//pDC->MoveTo(100, 100);
	//pDC->LineTo(500, 200);
	//调用RenderScene()渲染场景
	RenderScene();
	SetTimer(1, 500, NULL);

}

//渲染场景
bool CCG2019112346张柳GDI2DView::RenderScene()
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return false;
#ifdef USEMEMDC
	if (mRenderContext != nullptr)
		mRenderContext->setView(this); //更新渲染环境
#endif 
	//调用文档类的RenderScene
	return pDoc->RenderScene(mRenderContext);
}

// CCG2019112346张柳GDI2DView 打印


void CCG2019112346张柳GDI2DView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CCG2019112346张柳GDI2DView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CCG2019112346张柳GDI2DView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CCG2019112346张柳GDI2DView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}

void CCG2019112346张柳GDI2DView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CCG2019112346张柳GDI2DView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CCG2019112346张柳GDI2DView 诊断

#ifdef _DEBUG
void CCG2019112346张柳GDI2DView::AssertValid() const
{
	CView::AssertValid();
}

void CCG2019112346张柳GDI2DView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCG2019112346张柳GDI2DDoc* CCG2019112346张柳GDI2DView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCG2019112346张柳GDI2DDoc)));
	return (CCG2019112346张柳GDI2DDoc*)m_pDocument;
}
#endif //_DEBUG


// CCG2019112346张柳GDI2DView 消息处理程序


void CCG2019112346张柳GDI2DView::OnDrawCdc()
{
	// TODO: 在此添加命令处理程序代码
	/*
	  添加基于 GDI 相关类进行基本图形绘制（直线、圆、椭圆、矩形、多边形、
	  折线、曲线、圆弧、椭圆弧、弦、填充、文字等）及图形属性的编程（修改线型、
	  线宽、颜色、填充样式、文字样式等），掌握GDI 图形编程相关类及函数的用法。
	*/
	CClientDC dc(this);  //首先获取客户区绘制环境(相当于画板)

	//直线
	dc.MoveTo(100, 100);
	dc.LineTo(400, 200);
	//弦
	dc.Ellipse(700, 500, 800, 600);
	dc.MoveTo(700, 550);
	dc.LineTo(800, 550);
	//圆弧
	dc.Arc(500, 450, 600, 550, 500, 500, 600, 500);

	/*********************填充颜色及填充样式***********************/

	//紫色纯色填充
	CBrush newBrush1(RGB(198, 146, 245));
	dc.SelectObject(&newBrush1);

	dc.Ellipse(500, 100, 600, 200);	//圆	
	dc.Ellipse(100, 300, 300, 400);//椭圆

	//绿色竖条纹填充
	CBrush newBrush2(HS_HORIZONTAL, RGB(111, 245, 93));
	dc.SelectObject(&newBrush2);

	CPoint pt1[6] = { CPoint(700,100),CPoint(650,150), CPoint(650,200),
					 CPoint(700,250),CPoint(750,200), CPoint(750,150) }; //六个点
	dc.Polygon(pt1, 6);  //多边形

	/*CBrush newBrush2;
	newBrush2.CreateHatchBrush(HS_HORIZONTAL, RGB(111, 245, 93));
	dc.SelectObject(&newBrush2);

	CPoint pt1[6] = { CPoint(700,100),CPoint(650,150), CPoint(650,200),
					 CPoint(700,250),CPoint(750,200), CPoint(750,150) }; //六个点
	dc.Polygon(pt1, 6);
	newBrush2.DeleteObject();*/


	//蓝色竖条纹填充
	CBrush newBrush3(HS_VERTICAL, RGB(0, 108, 190));
	dc.SelectObject(&newBrush3);

	dc.Rectangle(450, 300, 500, 400);//矩形

	/***********************线颜色、线型、线宽***********************/

	//线宽1，虚线，红色
	CPen newPen1(PS_DASH, 1, RGB(245, 68, 51));
	dc.SelectObject(&newPen1);

	//直线
	dc.MoveTo(100, 120);
	dc.LineTo(400, 220);

	//线宽5，点状线，蓝色
	CPen newPen2(PS_DOT, 5, RGB(255, 0, 0));
	dc.SelectObject(&newPen2);
	//折线
	CPoint pt2[4] = { CPoint(600, 400),CPoint(650, 280), CPoint(700, 440),
					 CPoint(730, 400) }; //六个点
	dc.Polyline(pt2, 4);

	dc.Arc(800, 100, 900, 200, 750, 200, 950, 680);//曲线

	//线宽10，点状线，蓝色
	CPen newPen3(PS_DASHDOT, 10, RGB(190, 11, 98));
	dc.SelectObject(&newPen3);

	dc.Arc(100, 450, 300, 550, 150, 475, 370, 600);//椭圆弧

	/************************文字************************/
	CString text = L"计算机图形学";
	//文本框
	RECT rect;
	rect.left = 1400;
	rect.top = 100;
	rect.right = 500;
	rect.bottom = 500;

	//设置字体为微软雅黑
	CFont font;
	font.CreatePointFont(150, L"微软雅黑", &dc);
	dc.SelectObject(&font);

	//居中, 横向, 蓝色	
	COLORREF Color = dc.SetTextColor(RGB(40, 120, 190));
	dc.DrawText(text, &rect, DT_CENTER | DT_VCENTER);
	dc.SetTextColor(Color);

	//释放
	font.DeleteObject();
}

//画笔属性
COLORREF CCG2019112346张柳GDI2DView::PenColor() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return RGB(0, 0, 0);
	return pMainWnd->PenColor();
}
int CCG2019112346张柳GDI2DView::PenWidth() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return 1;
	return pMainWnd->PenWidth();
}
int CCG2019112346张柳GDI2DView::PenStyle() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return PS_SOLID;
	return pMainWnd->PenStyle();
}
//画刷属性
bool CCG2019112346张柳GDI2DView::UseBrush() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return false;
	return pMainWnd->UseBrush();
}
COLORREF CCG2019112346张柳GDI2DView::BrushColor() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return RGB(255, 255, 255);
	return pMainWnd->BrushColor();
}
int CCG2019112346张柳GDI2DView::BrushIndex() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return -1; // 0;
	return pMainWnd->BrushIndex();
}
//画线算法
int CCG2019112346张柳GDI2DView::LineAlgorithm() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return 0;
	return pMainWnd->LineAlgorithm();
}
//圆弧算法
int CCG2019112346张柳GDI2DView::CircleAlgorithm() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return 0;
	return pMainWnd->CircleAlgorithm();
}
//填充算法
int CCG2019112346张柳GDI2DView::FillAlgorithm() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return 0;
	return pMainWnd->FillAlgorithm();
}
int CCG2019112346张柳GDI2DView::SeedAlgorithm() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return 0;
	return pMainWnd->SeedAlgorithm();
}
//点阵区域的边界颜色
COLORREF CCG2019112346张柳GDI2DView::BoundColor() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return RGB(0, 0, 0);
	return pMainWnd->BoundColor();
}
//点阵区域的内点颜色
COLORREF CCG2019112346张柳GDI2DView::FloodColor() const
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (!pMainWnd)
		return RGB(255, 255, 255);
	return pMainWnd->FloodColor();
}
//状态栏上显示提示信息
void CCG2019112346张柳GDI2DView::Prompt(const CString& str)
{
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (pMainWnd != nullptr)
	{
		pMainWnd->ShowPrompt(str);
	}
}
//根据视口坐标获取对应场景坐标（二维）-调用场景类的ViewPortToWorld
Vec2d CCG2019112346张柳GDI2DView::ViewPortToWorld(const Vec2i& p)
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return Vec2d();
	return pDoc->ViewPorttoWorld(p);
}
Vec2i CCG2019112346张柳GDI2DView::WorldToViewPort(const Vec2d& p)
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return Vec2i();
	return pDoc->WorldtoViewPort(p);
}
//图形对象添加到场景
bool CCG2019112346张柳GDI2DView::addRenderable(CGRenderable* r)
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return false;
	bool ret = pDoc->addRenderable(r);
	return ret;
}
bool CCG2019112346张柳GDI2DView::delReaderable(CGRenderable* r)
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return false;
	bool ret = pDoc->delReaderable(r);
	return ret;
}
void CCG2019112346张柳GDI2DView::OnSize(UINT nType, int cx, int cy)
{
	CGDI2DView::OnSize(nType, cx, cy);
	// TODO: 在此处添加消息处理程序代码
	//根据客户区大小变化，修正视口，并保证观察窗口与视口比例
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->ClientResized(cx, cy);
}


void CCG2019112346张柳GDI2DView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	if (nChar == VK_ESCAPE) //如果按下了ESC键，则中断当前的绘制命令（如果正在执行）
	{
		if (mCommand)
		{
			mCommand->Cancel();
			delete mCommand;
			mCommand = nullptr;
		}
	}
	if (mCommand) //命令模式
		mCommand->OnKeyDown(nChar, nRepCnt, nFlags);
	CGDI2DView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CCG2019112346张柳GDI2DView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	if (mCommand) //命令模式
		mCommand->OnKeyUp(nChar, nRepCnt, nFlags);
	CGDI2DView::OnKeyUp(nChar, nRepCnt, nFlags);
}


void CCG2019112346张柳GDI2DView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnLButtonDblClk(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnLButtonDblClk(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnLButtonDown(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnLButtonDown(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnLButtonUp(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnLButtonUp(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnMButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnMButtonDown(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnMButtonDown(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnMButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnMButtonDblClk(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnMButtonDblClk(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnMButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnMButtonUp(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnMButtonUp(nFlags, point);
}


BOOL CCG2019112346张柳GDI2DView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnMouseWheel(nFlags, zDelta, Pos2i(pt.x, pt.y));
	return CGDI2DView::OnMouseWheel(nFlags, zDelta, pt);
}


void CCG2019112346张柳GDI2DView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值	

	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (pDoc != nullptr && pMainWnd != nullptr)
	{
		Vec2d v = pDoc->ViewPorttoWorld(Vec2i(point.x, point.y));
		CString str;
		str.Format(_T("视口坐标 ( %d, %d ) : 世界坐标 (%.2f , %.2f) "), point.x, point.y, v.x(), v.y());
		pMainWnd->ShowCoordOnStatusBar(str); //显示到状态栏
	}
	//命令模式，进一步根据当前的命令状态处理鼠标移动事件
	if (mCommand)
		mCommand->OnMouseMove(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnMouseMove(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// 此功能要求 Windows Vista 或更高版本。
	// _WIN32_WINNT 符号必须 >= 0x0600。
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CGDI2DView::OnMouseHWheel(nFlags, zDelta, pt);
}


void CCG2019112346张柳GDI2DView::OnRButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnRButtonDblClk(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnRButtonDblClk(nFlags, point);
}


void CCG2019112346张柳GDI2DView::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mCommand)
		mCommand->OnRButtonDblClk(nFlags, Pos2i(point.x, point.y));
	CGDI2DView::OnRButtonDown(nFlags, point);
}



//指针
void CCG2019112346张柳GDI2DView::OnCommandnone()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
}


void CCG2019112346张柳GDI2DView::OnUpdateCommandnone(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(!mCommand);
}

//图形对象的拾取（二维图形）
void CCG2019112346张柳GDI2DView::UpdatePicked(const Vec2d& p, double radius) //更新选择
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->UpdatePicked(p, radius);
		Invalidate();
		UpdateWindow();
	}
}
void CCG2019112346张柳GDI2DView::AppendPicked(const Vec2d& p, double radius) //添加选择
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->AppendPicked(p, radius);
		Invalidate();
		UpdateWindow();
	}
}

//拾取按钮
void CCG2019112346张柳GDI2DView::OnPickOne()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Pick2DRenderable(this);
}

void CCG2019112346张柳GDI2DView::OnUpdatePickOne(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dPickRenderable);
}


//全选按钮
void CCG2019112346张柳GDI2DView::OnPickAll()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->scene()->RenderableSelectAll();
	Invalidate();
	UpdateWindow();
}

void CCG2019112346张柳GDI2DView::OnUpdatePickAll(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
}
//撤销按钮
void CCG2019112346张柳GDI2DView::OnPickNone()
{
	// TODO: 在此添加命令处理程序代码
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	if (pMainWnd)
		pMainWnd->UnselectSceneTree();
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->scene()->RenderableUnselectAll();
	Invalidate();
	UpdateWindow();
}
//线段
void CCG2019112346张柳GDI2DView::OnLinesegment()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DLineSegment(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateLinesegment(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dLineSegment);
}

//直线
void CCG2019112346张柳GDI2DView::OnDraw2dline()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DLine(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateDraw2dline(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dLine);
}

//射线
void CCG2019112346张柳GDI2DView::OnRay()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DRay(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateRay(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dRay);
}

void CCG2019112346张柳GDI2DView::OnDrawBrokenLine()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DBrokenLine(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateDrawBrokenLine(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dPolyline);
}

void CCG2019112346张柳GDI2DView::OnDraw2dlineTime()
{
	// TODO: 在此添加命令处理程序代码
	if (mRenderContext == nullptr)return;
#ifdef USEMEMDC
	mRenderContext->setView(this); //更新渲染环境
#endif // !USEMEMDC
	//生成一定数量的直线段的端点坐标
	static Vec2iArray point1, point2;
	int num = 10000;
	if (point1.empty()) {
		srand(time(0));
		for (int i = 0; i < num; i++) {
			int x = rand() % 1400;
			int y = rand() % 800;
			point1.push_back(Vec2i(x, y));
		}
		for (int i = 0; i < num; i++) {
			int x = rand() % 1400;
			int y = rand() % 800;
			point2.push_back(Vec2i(x, y));
		}
	}


	//定义计时用的参数
	double fit;
	CString strFitin;
	LARGE_INTEGER frequency, start, end;

	QueryPerformanceFrequency(&frequency);
	//DDA算法
	QueryPerformanceCounter(&start); //绘制前计时
	//绘制
	int lineAlgrithm = CGView::mRenderContext->getView()->LineAlgorithm();
	for (int i = 0; i < num; i++) {
		if (lineAlgrithm == CGRenderContext::aLineDDA)
			mRenderContext->DDALine(point1.at(i), point2.at(i), RGB(255, 0, 0));
		else if (lineAlgrithm == CGRenderContext::aLineMidPoint)
			mRenderContext->MidPointLine(point1.at(i), point2.at(i), RGB(0, 255, 0));
		else if (lineAlgrithm == CGRenderContext::aLineBresenham)
			mRenderContext->BresenhamLine(point1.at(i), point2.at(i), RGB(0, 0, 255));
	}

	QueryPerformanceCounter(&end); //绘制结束计时

	//算出持续时间
	fit = (double)(end.QuadPart - start.QuadPart) / (double)frequency.QuadPart;
	if (lineAlgrithm == CGRenderContext::aLineDDA)
		strFitin.Format(_T("DDALine：%.6f"), fit);
	else if (lineAlgrithm == CGRenderContext::aLineMidPoint)
		strFitin.Format(_T("MidPointLine：%.6f"), fit);
	else if (lineAlgrithm == CGRenderContext::aLineBresenham)
		strFitin.Format(_T("BresenhamLine：%.6f"), fit);

	AfxMessageBox(strFitin);

#ifdef USEMEMDC
	((CGDI2DRenderContext*)mRenderContext)->SwapBackBuffer();
#endif // !USEMEMDC

}

//两点画圆
void CCG2019112346张柳GDI2DView::On2pointRadius()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DCircle(this);
}



void CCG2019112346张柳GDI2DView::OnUpdate2pointRadius(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dCircle);
}

//直径画圆
void CCG2019112346张柳GDI2DView::OnDiameterCircle()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DDiaCircle(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateDiameterCircle(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dDiaCircle);
}

//三点画圆
void CCG2019112346张柳GDI2DView::OnThreepointCircle()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2D3PointCircle(this);
}

void CCG2019112346张柳GDI2DView::OnUpdateThreepointCircle(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2d3PointCircle);
}

//三点画弧
void CCG2019112346张柳GDI2DView::On3pointArc()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2D3PointArc(this);
}


void CCG2019112346张柳GDI2DView::OnUpdate3pointArc(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2d3PointArc);
}

//点阵区域按钮
void CCG2019112346张柳GDI2DView::OnArea()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DSeedFill(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateArea(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2DSeedFill);
}

//一般多边形
void CCG2019112346张柳GDI2DView::OnDrawPolygon()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Create2DPolygon(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateDrawPolygon(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dPolygon);
}

//二维图形对象的几何变换（针对选择集中的对象）
void CCG2019112346张柳GDI2DView::Translate(double tx, double ty) //平移
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Translate(tx, ty);
		Invalidate();
		UpdateWindow();
	}
}
void CCG2019112346张柳GDI2DView::Rotate(double angle, double cx, double cy)//旋转（逆时针为正，度）
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Rotate(angle, cx, cy);
		Invalidate();
		UpdateWindow();
	}
}
void CCG2019112346张柳GDI2DView::Scale(double sx, double sy) //缩放
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Scale(sx, sy);
		Invalidate();
		UpdateWindow();
	}
}
void CCG2019112346张柳GDI2DView::Scale(double sx, double sy, double cx, double cy)
//缩放
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Scale(sx, sy, cx, cy);
		Invalidate();
		UpdateWindow();
	}
}
void CCG2019112346张柳GDI2DView::Scale(double sx, double sy, double cx, double cy, const Vec2d&
	xDir) //缩放
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Scale(sx, sy, cx, cy, xDir);
		Invalidate();
		UpdateWindow();
	}
}
void CCG2019112346张柳GDI2DView::ShearXYAxis(double shx, double shy) //沿X、Y轴错切
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->ShearXYAxis(shx, shy);
		Invalidate();
		UpdateWindow();
	}
}

//左移
void CCG2019112346张柳GDI2DView::OnTransformTranslateleft()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->Translate(-50, 0); //每次移动的距离可自定义一个常量，此处表示点击【左移】
	Invalidate();
	UpdateWindow();
}

//右移
void CCG2019112346张柳GDI2DView::OnTransformTranslatereft()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->Translate(50, 0); //每次移动的距离可自定义一个常量，此处表示点击【右移】
	Invalidate();
	UpdateWindow();
}

//上移
void CCG2019112346张柳GDI2DView::OnTransformTranslateup()
{
	// TODO: 在此添加命令处理程序代码
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->Translate(0, 50); //每次移动的距离可自定义一个常量，此处表示点击【上移】
	Invalidate();
	UpdateWindow();
}

//下移
void CCG2019112346张柳GDI2DView::OnTransformTranslatedown()
{
	// TODO: 在此添加命令处理程序代码
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->Translate(0, -50); //每次移动的距离可自定义一个常量，此处表示点击【下移】
	Invalidate();
	UpdateWindow();
}

//放大
void CCG2019112346张柳GDI2DView::OnAmplification()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->Scale(3, 3); //此处表示点击【放大】
	Invalidate();
	UpdateWindow();
}

//缩小
void CCG2019112346张柳GDI2DView::OnNarrow()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->Scale(0.5, 0.5); //此处表示点击【缩小】，
	Invalidate();
	UpdateWindow();
}

//关于x轴对称
void CCG2019112346张柳GDI2DView::OnXAxisymmetric()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->MirrorXAxis();
	Invalidate();
	UpdateWindow();
}

//关于y轴对称
void CCG2019112346张柳GDI2DView::OnYAxisymmetric()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->MirrorYAxis();
	Invalidate();
	UpdateWindow();
}

//关于原点对称
void CCG2019112346张柳GDI2DView::OnOriginAxisymmetric()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->MirrorOrigin();
	Invalidate();
	UpdateWindow();
}


//关于y=x对称
void CCG2019112346张柳GDI2DView::OnYxAxisymmetric()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->MirrorYeqPosX();
	Invalidate();
	UpdateWindow();
}


//关于y=-x对称
void CCG2019112346张柳GDI2DView::OnYXAxisymmetric()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->MirrorYeNegPX();
	Invalidate();
	UpdateWindow();
}

//关于x错切
void CCG2019112346张柳GDI2DView::OnXShear()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->ShearXAxis(0.5);
	Invalidate();
	UpdateWindow();
}


//关于y错切
void CCG2019112346张柳GDI2DView::OnYShear()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
		pDoc->ShearYAxis(0.5);
	Invalidate();
	UpdateWindow();
}

//自由平移
void CCG2019112346张柳GDI2DView::OnTransformTranslate()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Translate2DRenderable(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateTransformTranslate(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dTranslateRenderable);
}

//缩放
void CCG2019112346张柳GDI2DView::OnBigSmall()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new Scale2DRenderable(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateBigSmall(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dScaleRenderable);
}

//创建时钟
void CCG2019112346张柳GDI2DView::OnCreateClock()
{
	// TODO: 在此添加命令处理程序代码
	CClockDialog dlg;
	if (dlg.DoModal() == IDOK) //点击确定
	{
		CG2DClock* pClock = new CG2DClock(Vec2d(dlg.mlocationX, dlg.mlocationY), dlg.mClockRadius, dlg.flag);//建立时钟
		addRenderable(pClock);//添加到场景中
		Invalidate();
		UpdateWindow();
	}
}

//时钟响应
void CCG2019112346张柳GDI2DView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		if (pDoc->TimerCallback()) {
			Invalidate();
			UpdateWindow();
		}
	}

	CGDI2DView::OnTimer(nIDEvent);
}
//观察窗口宽度与视口宽度的比例
double CCG2019112346张柳GDI2DView::WidthFactorWindowtoViewPort()
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		return pDoc->WidthFactorWindowtoViewPort();
	}
	return 1.0;
}
//观察窗口高度与视口高度的比例
double CCG2019112346张柳GDI2DView::HeightFactorWindowtoViewPort()
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		return pDoc->HeightFactorWindowtoViewPort();
	}
	return 1.0;
}
//观察（二维）（保持与视口高宽比一致）
void CCG2019112346张柳GDI2DView::Move2DCamera(double tx, double ty) //频移观察窗口
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Move2DCamera(tx, ty);
	}
}
void CCG2019112346张柳GDI2DView::Zoom2DCamera(const Vec2d& lb, const Vec2d& rt) //观察窗口左下角、右上角
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Zoom2DCamera(lb, rt);
	}
}
void CCG2019112346张柳GDI2DView::Zoom2DCamera(double ratio) //给定观察窗口的缩放比例（）
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Zoom2DCamera(ratio);
	}
}
void CCG2019112346张柳GDI2DView::Rotate2DCamera(double angle) //转动相机（观察坐标系）
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Rotate2DCamera(angle);
	}
}
void CCG2019112346张柳GDI2DView::Reset2DCamera() //重置到默认参数（二维）
{
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Reset2DCamera();
	}
}

//扩大范围
void CCG2019112346张柳GDI2DView::OnZoomIn()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Zoom2DCamera(1.25);
	}
}

//移动视点
void CCG2019112346张柳GDI2DView::OnCameraPan()
{
	// TODO: 在此添加命令处理程序代码
	if (mCommand)
	{
		mCommand->Cancel();
		delete mCommand;
		mCommand = nullptr;
	}
	mCommand = new CG_NAMESPACE::Move2DCamera(this);
}


void CCG2019112346张柳GDI2DView::OnUpdateCameraPan(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(mCommand && mCommand->GetType() == cmd2dMoveCamera);
}

//缩小范围
void CCG2019112346张柳GDI2DView::OnZoomOut()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->Zoom2DCamera(0.8);
	}
}

//显示全部
void CCG2019112346张柳GDI2DView::OnShowAll()
{
	// TODO: 在此添加命令处理程序代码
	CCG2019112346张柳GDI2DDoc* pDoc = GetDocument();
	if (pDoc)
	{
		pDoc->ShowAll2DCamera();
	}
}
